<template>
    <Codemirror 
        :value="codeVal"
        :options="cmOption"
        border
        placeholder="测试占位符"
        :height="200"
        @change="onChange"
        ref="codeRef"
    ></Codemirror>
</template>

<script setup lang="ts">
    import Codemirror from "codemirror-editor-vue3";
    import type { CmComponentRef } from "codemirror-editor-vue3";
    // 代码高亮
    import "codemirror/mode/javascript/javascript.js";
    import "codemirror/mode/htmlmixed/htmlmixed.js";
    import "codemirror/mode/htmlembedded/htmlembedded.js";
    import "codemirror/mode/css/css.js";
    import "codemirror/mode/yaml/yaml.js";
    // 代码主题
    import "codemirror/theme/3024-day.css";
    import "codemirror/theme/3024-night.css";
    import "codemirror/theme/base16-dark.css";
    import "codemirror/theme/base16-light.css";
    import "codemirror/theme/darcula.css";
    import "codemirror/theme/dracula.css";

    // 语法校验
    import "codemirror/addon/lint/yaml-lint.js"
    import "codemirror/addon/lint/lint.css"
    import "codemirror/addon/lint/lint.js"

    // 折叠相关
    import "codemirror/addon/fold/foldgutter.css"
    import "codemirror/addon/fold/foldgutter.js"
    import "codemirror/addon/fold/foldcode.js"
    import "codemirror/addon/fold/xml-fold.js"


    import { nextTick, reactive, ref, watch } from "vue";

    window.jsyaml = require('js-yaml')

    const codeRef = ref<CmComponentRef | null>(null)
    type optionType = {
        mode: string,
        hintOptions?: object,
        theme?: string,
        lint?: boolean,
        gutters?: string[],
        lineWrapping?: boolean,
        lineNumbers?: boolean,
    }
    const props = defineProps<{
        code: string,
        option: optionType
    }>()
    const codeVal = ref<string>('')
    const cmOption = ref<optionType>({
        mode: '',
        theme: '',
        lint: false,
        gutters: [],
        lineWrapping: false,
        lineNumbers: false,
    })

    // 内容
    watch(() => props.code, (newVal, oldVal) => {
        debugger
        if (newVal && codeVal.value !== newVal) {
            codeVal.value = newVal
        }
    }, {
        immediate: true
    })
    // 代码语言
    watch(() => props.option.mode, (newVal, oldVal) => {
        cmOption.value.mode = newVal
        cmOption.value.lint = false
        nextTick(() => {
            cmOption.value.lint = true
        })
    }, {
        immediate: true,
    })
    // 是否开启校验
    watch(() => props.option.lint, (newVal, oldVal) => {
        cmOption.value.lint = newVal
    }, {
        immediate: true,
    })
    // 侦听gutters
    watch(() => props.option.gutters, (newVal, oldVal) => {
        if (newVal) {
            cmOption.value.gutters = [...newVal]
        }
    }, {
        immediate: true
    })
    // 侦听主题
    watch(() => props.option.theme, (newVal, oldVal) => {
        if (newVal) {
            cmOption.value.theme = newVal
        }
    }, {
        immediate: true
    })
    // 侦听自动换行
    watch(() => props.option.lineWrapping, (newVal, oldVal) => {
        if (newVal) {
            cmOption.value.lineWrapping = newVal
        }
    }, {
        immediate: true
    })

    // 侦听行号
    watch(() => props.option.lineNumbers, (newVal, oldVal) => {
        if (newVal) {
            cmOption.value.lineNumbers = newVal
        }
    }, {
        immediate: true
    })
    const emits = defineEmits<{
        (e: 'change', val: string):void
    }>()


    // 内容改变触发
    function onChange (val: any) {
        // emits('Change')
        codeVal.value = val
        emits('change', val)
    }
    

</script>

<style lang="less" scoped>
</style>